/*
 * @Copyright: 2023 - 2023 www.hoperun.com Inc. All rights reserved.
 */

package com.lifeservice.util;

import com.alibaba.fastjson2.JSONObject;
import com.lifeservice.common.utils.StringUtils;
import com.lifeservice.console.domain.LifeWorkClass;
import com.lifeservice.console.domain.ScheduInfo;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalTime;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

/**
 * @author liu_yifeng
 * @function 排班工具类
 * @date 2023/2/27 11:30
 */
@Slf4j
public class ScheduUtil {

    /**
     * 获取一天的排班，如果最后一班结束时间超过了下班时间，则丢弃最后一班
     *
     * @param perServiceNum  单位服务人数
     * @param perWorkMinute  单位服务时长
     * @param date           日期 YYYY-MM-DD 格式
     * @param workStartTime  工作开始时间 9：00
     * @param workEndTime    工作结束时间 18：00
     * @param sleepStartTime 休息开始时间 12：00
     * @param sleepEndTime   休息结束时间 13：00
     * @return 排班信息
     */
    public static ScheduInfo getScheduling(Integer perServiceNum, Integer perWorkMinute, String date, String workStartTime, String workEndTime, String sleepStartTime, String sleepEndTime) {
        ScheduInfo scheduInfo = new ScheduInfo();
        scheduInfo.setDay(date);
        Integer year = Integer.parseInt(date.split("-")[0]);
        Integer month = Integer.parseInt(date.split("-")[1]);
        Integer day = Integer.parseInt(date.split("-")[2]);
        // 如果没有休息时间，则按照工作开始结束时间切分
        if (StringUtils.isEmpty(sleepStartTime) || StringUtils.isEmpty(sleepEndTime)) {
            List<LifeWorkClass> workClassList = genWorkTimeInfoList(workStartTime, workEndTime, year, month, day, perWorkMinute, perServiceNum, scheduInfo, 1);
            scheduInfo.setWorkClassList(workClassList);
        } else {// 否则按照工作开始时间-休息开始时间  休息结束时间-工作结束时间 切分
            String start1 = workStartTime;
            String end1 = sleepStartTime;
            List<LifeWorkClass> workTimeInfoList1 = genWorkTimeInfoList(start1, end1, year, month, day, perWorkMinute, perServiceNum, scheduInfo, 1);
            String start2 = sleepEndTime;
            String end2 = workEndTime;
            List<LifeWorkClass> workTimeInfoList2 = genWorkTimeInfoList(start2, end2, year, month, day, perWorkMinute, perServiceNum, scheduInfo, workTimeInfoList1.size() + 1);
            workTimeInfoList1.addAll(workTimeInfoList2);
            scheduInfo.setWorkClassList(workTimeInfoList1);
        }
        return scheduInfo;
    }

    /**
     * 工作时间表
     *
     * @param workStartTime 工作开始时间
     * @param workEndTime   工作结束时间
     * @param year          年
     * @param month         月
     * @param day           日
     * @param perWorkMinute 单位服务时长
     * @param perServiceNum 单位服务人数
     * @param scheduInfo    排班对象
     * @return 工作时间表
     */
    private static List<LifeWorkClass> genWorkTimeInfoList(String workStartTime, String workEndTime, int year, int month, int day, int perWorkMinute, int perServiceNum, ScheduInfo scheduInfo, int workClass) {
        List<LifeWorkClass> workTimeInfoList = new LinkedList<>();
        Integer starthour = Integer.parseInt(workStartTime.split(":")[0]);
        Integer startminute = Integer.parseInt(workStartTime.split(":")[1]);
        Calendar start = Calendar.getInstance();
        start.set(year, month - 1, day, starthour, startminute);
        scheduInfo.setWeek(LifeServiceConstants.getWeekConvertMap().get(start.get(Calendar.DAY_OF_WEEK)));
        Integer endhour = Integer.parseInt(workEndTime.split(":")[0]);
        Integer endminute = Integer.parseInt(workEndTime.split(":")[1]);
        Calendar end = Calendar.getInstance();
        end.set(year, month - 1, day, endhour, endminute);
        int i = workClass;
        while (start.before(end)) {
            LifeWorkClass info = new LifeWorkClass();
            String thisStartWorkTime = LocalTime.of(start.get(Calendar.HOUR_OF_DAY), start.get(Calendar.MINUTE)).toString();
            start.add(Calendar.MINUTE, perWorkMinute);
            if (start.get(Calendar.HOUR_OF_DAY) == end.get(Calendar.HOUR_OF_DAY) && start.get(Calendar.MINUTE) > end.get(Calendar.MINUTE)) {
                break;
            }
            String thisEndWorkTime = LocalTime.of(start.get(Calendar.HOUR_OF_DAY), start.get(Calendar.MINUTE)).toString();
            info.setWorkTime(thisStartWorkTime + "-" + thisEndWorkTime);
            info.setStock(perServiceNum);
            info.setWorkClass(String.valueOf(i));
            workTimeInfoList.add(info);
            i++;
        }
        return workTimeInfoList;
    }

    public static void main(String[] args) {
        ScheduInfo info = getScheduling(10, 10, "2023-3-15", "9:00", "18:00", "12:00", "13:30");
        log.info(JSONObject.toJSONString(info));
    }
}
